package com.common.data.desensitization.common.utils;

import com.common.data.desensitization.common.annotation.DesensitizationRule;
import com.common.data.desensitization.common.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * @ClassName DesensitizationServiceUtil
 * @Description 脱敏工具类
 * @Author shiyuan
 * @Date 2025/5/18 12:35
 * @Version 1.0
 **/
@Component
public class DesensitizationServiceUtil {

    private static final Logger logger = LoggerFactory.getLogger(DesensitizationServiceUtil.class);
    @Autowired
    private DesensitizePrefixKeepHandler prefixKeepHandler;
    @Autowired
    private DesensitizeSuffixKeepHandler suffixKeepHandler;
    @Autowired
    private DesensitizeMiddleMaskHandler middleMaskHandler;
    @Autowired
    private DesensitizePhoneHandler phoneHandler;
    @Autowired
    private DesensitizeEmailHandler emailHandler;
    @Autowired
    private DesensitizeIdCardHandler idCardHandler;
    @Autowired
    private DesensitizeBankCardHandler bankCardHandler;
    @Autowired
    private DesensitizeByRegexHandler regexHandler;

    /**
     * 根据指定的脱敏规则对字段值进行数据脱敏处理
     *
     * @param originalValue 原始字段值，需要脱敏处理的字符串
     * @param rule 脱敏规则配置，包含策略类型和具体参数
     * @return 脱敏后的字符串。当处理失败时保守返回原始值
     *
     * @apiNote 支持的脱敏策略包括：
     * - PREFIX_KEEP: 保留前n位明文，其余用掩码字符替换
     * - SUFFIX_KEEP: 保留后n位明文，其余用掩码字符替换
     * - MIDDLE_MASK: 保留前后指定位数明文，中间用掩码字符或指定字符串替换
     * - 特定格式处理（手机号、邮箱、身份证、银行卡）
     * - 正则表达式替换
     * - 自定义处理器
     */
    public String desensitizeField(String originalValue, DesensitizationRule rule) {
        if (!StringUtils.hasText(originalValue)) {
            return originalValue;
        }

        String result = originalValue;
        try {
            switch (rule.strategy()) {
                case PREFIX_KEEP:
                    result = prefixKeepHandler.desensitize(originalValue, rule);
                    break;
                case SUFFIX_KEEP:
                    result = suffixKeepHandler.desensitize(originalValue,rule);
                    break;
                case MIDDLE_MASK:
                    result = middleMaskHandler.desensitize(originalValue, rule);
                    break;
                case PHONE:
                    result = phoneHandler.desensitize(originalValue, rule);
                    break;
                case EMAIL:
                    result = emailHandler.desensitize(originalValue, rule);
                    break;
                case ID_CARD:
                    result = idCardHandler.desensitize(originalValue, rule);
                    break;
                case BANK_CARD:
                    result = bankCardHandler.desensitize(originalValue, rule);
                    break;
                case REGEX_REPLACE:
                    result = regexHandler.desensitize(originalValue, rule);
                    break;
                case CUSTOM_HANDLER:
                    if (rule.customHandler() != null && rule.customHandler() != DesensitizationHandler.class) {
                        DesensitizationHandler handler = rule.customHandler().getDeclaredConstructor().newInstance();
                        result = handler.desensitize(originalValue, rule);
                    } else {
                        logger.warn("未指定自定义处理程序或自定义处理程序未继承接口规范: {}", rule.jsonPath());
                    }
                    break;
                default:
                    if (rule.customHandler() != null && rule.customHandler() != DesensitizationHandler.class) {
                        DesensitizationHandler handler = rule.customHandler().getDeclaredConstructor().newInstance();
                        result = handler.desensitize(originalValue, rule);
                    } else {
                        result = middleMaskHandler.desensitize(originalValue, rule);
                    }
            }
        } catch (Exception e) {
            logger.error("脱敏过程中出错值为'{}' 脱敏规则是 '{}': {}", originalValue, rule.jsonPath(), e.getMessage(), e);
            return originalValue; // 保守起见，返回原值
        }
        return result;
    }
}
